package com.sun.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sun.common.Exception.CustomException;
import com.sun.dto.PurchaseDto;
import com.sun.entity.PurchaseDetail;
import com.sun.entity.PurchaseHead;
import com.sun.mapper.PurchaseHeadMapper;
import com.sun.service.PurchaseDetailService;
import com.sun.service.PurchaseHeadService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Project: hospitalDrugInformationManagement
 * @Author: 86178
 * @Date: 2023/3/21 15:33
 * @FileName: PurchaseHeadServiceImpl
 * @Description: ""
 */
@SuppressWarnings("all")
@Service
public class PurchaseHeadServiceImpl extends ServiceImpl<PurchaseHeadMapper, PurchaseHead> implements PurchaseHeadService {

    @Autowired
    private PurchaseDetailService purchaseDetailService;

    @Autowired
    private PurchaseHeadMapper purchaseHeadMapper;

    @Override
    public IPage<PurchaseDto> selectPurchaseDtoListPage(IPage<PurchaseDto> page, String userName, String supplierName, Integer status,
                                                        LocalDateTime startTime, LocalDateTime endTime) {
        return purchaseHeadMapper.selectPurchaseDtoListPage(page, userName, supplierName, status, startTime, endTime);
    }

    @Override
    public List<PurchaseDto> selectPurchaseDtoList(String userName, String supplierName, Integer status, LocalDateTime startTime, LocalDateTime endTime) {
        return purchaseHeadMapper.selectPurchaseDtoList(userName, supplierName, status, startTime, endTime);
    }

    /**
     * 新增采购计划
     *
     * @param purchaseDto
     * @return
     */
    @Override
    public Boolean saveWithPurchaseDetail(PurchaseDto purchaseDto) {
        //保存采购单的基本信息到采购单单头表purchase_head
        purchaseDto.setStatus(0);
        boolean a = this.save(purchaseDto);

        //采购单单头的编号
        Long purchaseId = purchaseDto.getPurchaseId();

        List<PurchaseDetail> purchaseDetails = purchaseDto.getPurchaseDetails();
        purchaseDetails = purchaseDetails.stream().map((item) -> {
            item.setPurchaseId(purchaseId);
            return item;
        }).collect(Collectors.toList());
        //保存采购单具体的数据到采购单单目表purchase_detail
        boolean b = purchaseDetailService.saveBatch(purchaseDetails);
        return a && b;
    }

    /**
     * 根据id查询采购单和对应的药品信息
     *
     * @param id
     * @return
     */
    @Override
    public PurchaseDto getByIdWithPurchaseDetail(Long id) {
        PurchaseDto purchaseDto = new PurchaseDto();
        //查询采购单基本信息，从purchase_head表查询
        PurchaseHead purchaseHead = this.getById(id);
        BeanUtils.copyProperties(purchaseHead, purchaseDto);

        //查询当前采购单对应的药品信息，从purchase_detail表查询
        LambdaQueryWrapper<PurchaseDetail> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(PurchaseDetail::getPurchaseId, purchaseHead.getPurchaseId());
        List<PurchaseDetail> purchaseDetails = purchaseDetailService.list(lambdaQueryWrapper);
        purchaseDto.setPurchaseDetails(purchaseDetails);

        return purchaseDto;
    }

    /**
     * 更新采购单，同时更新对应的药品信息
     *
     * @param purchaseDto
     * @return
     */
    @Override
    public void updateWithPurchaseDetail(PurchaseDto purchaseDto) {
        //先更新采购单单头的信息
        this.updateById(purchaseDto);
        //再更新采购单单目的信息
        //先把采购单目查询出来和新的比较如果存在就更新，不存在就新增，新的数据没有就删除
        //查询历史数据
        LambdaQueryWrapper<PurchaseDetail> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(PurchaseDetail::getPurchaseId, purchaseDto.getPurchaseId());
        List<PurchaseDetail> oldData = purchaseDetailService.list(lambdaQueryWrapper);
        //新的数据
        List<PurchaseDetail> dtoPurchaseDetails = purchaseDto.getPurchaseDetails();
        //进行比较
        // 遍历新数据列表
        for (PurchaseDetail newData : dtoPurchaseDetails) {
            boolean flag = true; // 是否需要新增
            int i = 0; // 在历史数据列表中的位置
            // 遍历历史数据列表
            for (i = 0; i < oldData.size(); i++) {
                PurchaseDetail oldPurchaseDetail = oldData.get(i);
                // 比较历史数据和新数据
                if (newData.getId() != null && newData.getId().equals(oldPurchaseDetail.getId())) {
                    // 需要更新
                    flag = false;
                    purchaseDetailService.updateById(newData);
                    break;
                }
            }
            if (flag) {
                // 需要新增
                newData.setPurchaseId(purchaseDto.getPurchaseId());
                purchaseDetailService.save(newData);
            }
        }

        for (PurchaseDetail oldItem : oldData) {
            boolean exist = false; // 是否存在于新数据列表中
            // 判断历史数据是否存在于新数据列表中
            for (PurchaseDetail item : dtoPurchaseDetails) {
                if (oldItem.getId().equals(item.getId())) {
                    exist = true;
                    break;
                }
            }
            if (!exist) {
                // 需要删除
                purchaseDetailService.removeById(oldItem.getId());
            }
        }
    }

    /**
     * 根据id删除采购单
     *
     * @param ids
     * @return
     */
    @Override
    public Boolean batchDeleteByIds(List<Long> ids) {
        //查询采购单状态，确定是否可用删除
        LambdaQueryWrapper<PurchaseHead> lambdaQueryWrapper = new LambdaQueryWrapper();
        lambdaQueryWrapper.in(PurchaseHead::getPurchaseId, ids);
        lambdaQueryWrapper.ne(PurchaseHead::getStatus, 0);

        int count = this.count(lambdaQueryWrapper);
        if (count > 0) {
            //如果不能删除，抛出一个业务异常
            throw new CustomException("采购单正在采购或已采购，不能删除");
        }

        //如果可以删除，先删除采购单头表中的数据---purchase_head
        boolean a = this.removeByIds(ids);

        //delete from purchase_detail where purchase_id in (1,2,3)
        LambdaQueryWrapper<PurchaseDetail> lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
        lambdaQueryWrapper1.in(PurchaseDetail::getPurchaseId, ids);
        //删除关系表中的数据----purchase_detail
        boolean b = purchaseDetailService.remove(lambdaQueryWrapper1);
        return a && b;
    }

    /**
     * 根据id和status修改采购单状态
     *
     * @param status
     * @param ids
     * @return
     */
    @Override
    public void updateStatusByIds(Integer status, List<Long> ids) {
        //  采购单具体的状态 由前端修改并返回，该方法传入的status是修改之后的状态，可以直接根据一个或多个采购id进行查询并修改
        LambdaQueryWrapper<PurchaseHead> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(ids != null, PurchaseHead::getPurchaseId, ids);

        List<PurchaseHead> purchaseHeadList = this.list(lambdaQueryWrapper);
        if (purchaseHeadList != null) {
            for (PurchaseHead item : purchaseHeadList) {
                item.setStatus(status);
                this.updateById(item);
            }
        }
    }
}
